<template>
  <div 
    :class="[
      'bx-calendar',
      'bx-glass',
      {
        [`bx-calendar--${size}`]: size
      }
    ]"
  >
    <div class="bx-calendar__header">
      <BxButton 
        variant="text" 
        size="small" 
        @click="prevYear"
      >
        <BxIcon name="double-chevron-left" />
      </BxButton>
      <BxButton 
        variant="text" 
        size="small" 
        @click="prevMonth"
      >
        <BxIcon name="chevron-left" />
      </BxButton>
      <span class="bx-calendar__header-text">
        {{ currentYear }}年 {{ currentMonth + 1 }}月
      </span>
      <BxButton 
        variant="text" 
        size="small" 
        @click="nextMonth"
      >
        <BxIcon name="chevron-right" />
      </BxButton>
      <BxButton 
        variant="text" 
        size="small" 
        @click="nextYear"
      >
        <BxIcon name="double-chevron-right" />
      </BxButton>
    </div>
    
    <div class="bx-calendar__weekdays">
      <span v-for="day in weekdays" :key="day">{{ day }}</span>
    </div>
    
    <div class="bx-calendar__days">
      <span 
        v-for="(day, index) in daysInMonth"
        :key="index"
        :class="[
          'bx-calendar__day',
          {
            'bx-calendar__day--prev-month': day.type === 'prev',
            'bx-calendar__day--next-month': day.type === 'next',
            'bx-calendar__day--current-month': day.type === 'current',
            'bx-calendar__day--selected': isSelected(day),
            'bx-calendar__day--today': isToday(day),
            'bx-calendar__day--disabled': day.disabled
          }
        ]"
        @click="handleDayClick(day)"
      >
        {{ day.date.getDate() }}
        <div v-if="$slots.dateCell" class="bx-calendar__date-cell">
          <slot name="dateCell" :date="day.date" :type="day.type"></slot>
        </div>
      </span>
    </div>
    
    <div class="bx-calendar__footer">
      <BxButton variant="text" size="small" @click="selectToday">今天</BxButton>
    </div>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue'
import BxIcon from '../basic/BxIcon.vue'
import BxButton from '../basic/BxButton.vue'

export default {
  name: 'BxCalendar',
  components: {
    BxIcon,
    BxButton
  },
  props: {
    modelValue: {
      type: Date,
      default: null
    },
    size: {
      type: String,
      default: 'medium',
      validator: (value) => ['small', 'medium', 'large'].includes(value)
    },
    disabledDate: {
      type: Function,
      default: () => false
    }
  },
  emits: ['update:modelValue', 'change'],
  setup(props, { emit }) {
    const selectedDate = ref(props.modelValue || new Date())
    const panelDate = ref(selectedDate.value) // 用于面板显示的日期

    const currentYear = computed(() => panelDate.value.getFullYear())
    const currentMonth = computed(() => panelDate.value.getMonth())

    const weekdays = ['日', '一', '二', '三', '四', '五', '六']

    const daysInMonth = computed(() => {
      const days = []
      const year = currentYear.value
      const month = currentMonth.value

      // 上个月的最后一天
      const prevMonthLastDay = new Date(year, month, 0).getDate()
      // 当前月的第一天是星期几
      const currentMonthFirstDayWeek = new Date(year, month, 1).getDay()
      // 当前月的总天数
      const currentMonthDays = new Date(year, month + 1, 0).getDate()

      // 填充上个月的日期
      for (let i = 0; i < currentMonthFirstDayWeek; i++) {
        const date = new Date(year, month - 1, prevMonthLastDay - currentMonthFirstDayWeek + 1 + i)
        days.push({ date, type: 'prev', disabled: props.disabledDate(date) })
      }

      // 填充当前月的日期
      for (let i = 1; i <= currentMonthDays; i++) {
        const date = new Date(year, month, i)
        days.push({ date, type: 'current', disabled: props.disabledDate(date) })
      }

      // 填充下个月的日期
      const remainingDays = 42 - days.length // 6行7列共42个格子
      for (let i = 1; i <= remainingDays; i++) {
        const date = new Date(year, month + 1, i)
        days.push({ date, type: 'next', disabled: props.disabledDate(date) })
      }
      return days
    })

    const prevMonth = () => {
      panelDate.value = new Date(currentYear.value, currentMonth.value - 1, 1)
    }

    const nextMonth = () => {
      panelDate.value = new Date(currentYear.value, currentMonth.value + 1, 1)
    }

    const prevYear = () => {
      panelDate.value = new Date(currentYear.value - 1, currentMonth.value, 1)
    }

    const nextYear = () => {
      panelDate.value = new Date(currentYear.value + 1, currentMonth.value, 1)
    }

    const handleDayClick = (day) => {
      if (day.disabled) return
      selectedDate.value = day.date
      panelDate.value = day.date // 同步面板日期
      emit('update:modelValue', selectedDate.value)
      emit('change', selectedDate.value)
    }

    const isSelected = (day) => {
      if (!selectedDate.value) return false
      return day.date.toDateString() === selectedDate.value.toDateString()
    }

    const isToday = (day) => {
      const today = new Date()
      return day.date.toDateString() === today.toDateString()
    }

    const selectToday = () => {
      selectedDate.value = new Date()
      panelDate.value = new Date()
      emit('update:modelValue', selectedDate.value)
      emit('change', selectedDate.value)
    }

    watch(() => props.modelValue, (newVal) => {
      selectedDate.value = newVal || new Date()
      panelDate.value = selectedDate.value
    })

    return {
      selectedDate,
      currentYear,
      currentMonth,
      weekdays,
      daysInMonth,
      prevMonth,
      nextMonth,
      prevYear,
      nextYear,
      handleDayClick,
      isSelected,
      isToday,
      selectToday
    }
  }
}
</script>

<style scoped>
.bx-calendar {
  width: 320px;
  border: 1px solid var(--bx-glass-border);
  border-radius: var(--bx-radius-large);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  padding: 16px;
  font-family: var(--bx-font-family);
}

.bx-calendar--small {
  width: 280px;
}

.bx-calendar--large {
  width: 360px;
}

.bx-calendar__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.bx-calendar__header-text {
  font-size: 16px;
  font-weight: 600;
  color: var(--bx-text-primary);
}

.bx-calendar__weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  font-size: 12px;
  color: var(--bx-text-secondary);
  margin-bottom: 8px;
}

.bx-calendar__days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.bx-calendar__day {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  cursor: pointer;
  transition: all var(--bx-transition-fast);
  font-size: 14px;
  color: var(--bx-text-primary);
}

.bx-calendar--small .bx-calendar__day {
  width: 32px;
  height: 32px;
  font-size: 13px;
}

.bx-calendar--large .bx-calendar__day {
  width: 40px;
  height: 40px;
  font-size: 15px;
}

.bx-calendar__day:hover {
  background: var(--bx-glass-bg-hover);
}

.bx-calendar__day--prev-month,
.bx-calendar__day--next-month {
  color: var(--bx-text-tertiary);
}

.bx-calendar__day--selected {
  background: rgba(0, 122, 255, 0.8);
  color: #fff;
}

.bx-calendar__day--selected:hover {
  background: rgba(0, 122, 255, 0.9);
}

.bx-calendar__day--today {
  border: 1px solid rgba(0, 122, 255, 0.5);
}

.bx-calendar__day--disabled {
  opacity: 0.4;
  cursor: not-allowed;
  background: transparent !important;
  color: var(--bx-text-tertiary) !important;
}

.bx-calendar__date-cell {
  font-size: 10px;
  color: var(--bx-text-secondary);
  margin-top: 2px;
}

.bx-calendar__footer {
  margin-top: 16px;
  border-top: 1px solid var(--bx-glass-border);
  padding-top: 12px;
  text-align: right;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bx-calendar {
    width: 100%;
    padding: 12px;
  }
  
  .bx-calendar__day {
    width: 32px;
    height: 32px;
    font-size: 13px;
  }
  
  .bx-calendar--small .bx-calendar__day {
    width: 28px;
    height: 28px;
    font-size: 12px;
  }
  
  .bx-calendar--large .bx-calendar__day {
    width: 36px;
    height: 36px;
    font-size: 14px;
  }
}
</style>

